#ifndef UID_MAP_H
#define UID_MAP_H

#include "uid.h"

#include <stdbool.h>

#define MAP_STRUCT_NAME uidmap_s
#define MAP_TYPE uidmap_t
#define MAP_KEY uid_t
#define MAP_VALUE int //CHENGE THIS!

#define MAP_SET_FUNC setUIDMap
#define MAP_GET_FUNC getUIDMap
#define MAP_DEL_FUNC delUIDMap

#define MAP_ELEM_PRED uidInMap
#define MAP_EQ_PRED uidMapEq

#define MAP_NULL_FUNC emptyUIDMap
#define MAP_FREE_FUNC freeUIDMap

struct MAP_STRUCT_NAME;
typedef struct MAP_STRUCT_NAME* MAP_TYPE;

/*
 * Gets the value accosiated with 'key'.
 *
 * If no value is accosiated with 'key',
 * 'def' is returned.
 */
MAP_VALUE MAP_GET_FUNC(MAP_KEY key, MAP_VALUE  def, MAP_TYPE map);

/*
 * Sets 'val' to be the value associated with 'key'.
 *
 * If another value is already associated with 'key'
 * it is overwritten.
 */
MAP_TYPE  MAP_SET_FUNC(MAP_KEY key, MAP_VALUE  val, MAP_TYPE map);

/*
 * Removes 'key' from map.
 *
 * If 'val' is non-null, it will be set to the, if any,
 * value associated with 'key'.
 */ 
MAP_TYPE  MAP_DEL_FUNC(MAP_KEY key, MAP_VALUE* val, MAP_TYPE map);

/*
 * Checks if 'key' is in 'map'. 
 */ 
bool MAP_ELEM_PRED(MAP_KEY key, MAP_TYPE map);

/*
 * Does a proper (non-pointer-comparison) equality
 * check of two maps.
 */
bool MAP_EQ_PRED(MAP_TYPE mapA, MAP_TYPE mapB);

/*
 * Instantiates an empty map (usually a pointer to the leaf node).
 */ 
MAP_TYPE MAP_NULL_FUNC(void);

/*
 * Frees up any memory used by the map. 
 */ 
void     MAP_FREE_FUNC(MAP_TYPE map);

void dumpMap(MAP_TYPE map, int depth);
bool validateStructure(MAP_TYPE map);
int validateMap(MAP_TYPE map);

/* Free up the namespace for other
 * Map implementations, unless
 * we are implementing this map.
 */
#ifndef IS_MAP_IMPLEMENTATION
#undef MAP_STRUCT_NAME
#undef MAP_TYPE
#undef MAP_KEY
#undef MAP_VALUE

#undef MAP_SET_FUNC
#undef MAP_GET_FUNC
#undef MAP_DEL_FUNC

#undef MAP_ELEM_PRED
#undef MAP_EQ_PRED

#undef MAP_NULL_FUNC
#undef MAP_FREE_FUNC
#endif

#endif
